home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Tool Chest / Localization Tools / FMAT Editor / FMAT Editor 1.0.1 sources / Source / NumberParts.c < prev   
Encoding:
C/C++ Source or Header  |  1993-11-08  |  10.8 KB  |  407 lines  |  [TEXT/KAHL]

  1. #include "FMAT.h"
  2.  
  3.  
  4. /* GetButtonStr: Retrieve string from NumberParts for the requested token's button */
  5. static void GetButtonStr( NumberParts *parts, short tok, StringPtr s )
  6. {
  7.     WideChar            *wc;
  8.     StringPtr            p;
  9.  
  10.     short                numChars;
  11.     short                i, len;
  12.  
  13.  
  14.     switch( tok ) {
  15.  
  16.     default:
  17.         numChars = 1;
  18.         wc = &parts->data[ tok - 1 ];
  19.         break;
  20.  
  21.     case tokPEPlus:
  22.         numChars = parts->pePlus.size + 1;
  23.         wc = parts->pePlus.data;
  24.         break;
  25.  
  26.     case tokPEMinus:
  27.         numChars = parts->peMinus.size + 1;
  28.         wc = parts->peMinus.data;
  29.         break;
  30.  
  31.     case tokPEMinusPlus:
  32.         numChars = parts->peMinusPlus.size + 1;
  33.         wc = parts->peMinusPlus.data;
  34.         break;
  35.     }
  36.  
  37.     /* Copy wide characters */
  38.     p = s + 1;
  39.     len = 0;
  40.  
  41.     for( i = 0; i < numChars; i++, wc++ ) {
  42.  
  43.         if( wc->a[ 0 ]) {
  44.             *p++ = wc->a[ 0 ];
  45.             len++;
  46.         }
  47.  
  48.         if( wc->a[ 1 ]) {
  49.             *p++ = wc->a[ 1 ];
  50.             len++;
  51.         }
  52.     }
  53.  
  54.     s[ 0 ] = len;
  55. }
  56.  
  57. /* NewButtonRow: Start a new row of buttons */
  58. static void NewButtonRow( Point *where, short lineHeight )
  59. {
  60.     where->h = 2;
  61.     where->v += lineHeight + 8;
  62. }
  63.  
  64. /* MakeButtonRect: Size and position the rectangle needed to hold this button's name */
  65. static void MakeButtonRect( NumberPartsPaletteHandle thePalette, NumberParts *parts,
  66.                         short tok, Point *where, short lineHeight, short widMax )
  67. {
  68.     Rect                        r;
  69.     Str31                        token;
  70.  
  71.     short                        tokWidth;
  72.  
  73.  
  74.     GetButtonStr( parts, tok, token );
  75.     tokWidth = StringWidth( token );
  76.     if( tokWidth < widMax )
  77.         tokWidth = widMax;
  78.  
  79.     SetRect( &r, 0, 0, tokWidth + 6, lineHeight + 6 );
  80.  
  81.     if( where->h + r.right > ( *thePalette )->fw.wind->portRect.right - 2 )
  82.         NewButtonRow( where, lineHeight );
  83.  
  84.     OffsetRect( &r, where->h, where->v );
  85.     where->h = r.right + 2;
  86.  
  87.     ( *thePalette )->buttonList[ tok - 1 ] = r;
  88. }
  89.  
  90. /* NewNumberPartsPalette: Create a new number parts palette */
  91. NumberPartsPaletteHandle NewNumberPartsPalette( rFMATHandle myFMAT )
  92. {
  93.     Point                        where;
  94.  
  95.     WindowPtr                    theWindow;
  96.     NumberPartsPaletteHandle    thePalette;
  97.  
  98.  
  99.     /* Allocate storage */
  100.     thePalette = ( NumberPartsPaletteHandle )NewHandle( sizeof( NumberPartsPalette ));
  101.     if( !thePalette )
  102.         return 0;
  103.  
  104.     /* Get parent (dialog) window to find palette's default position */
  105.     theWindow = ( WindowPtr )( *myFMAT )->w.wind;
  106.     SetPort( theWindow );
  107.  
  108.     /* Position beside parent */
  109.     SetPt( &where, theWindow->portRect.right + 5, theWindow->portRect.top );
  110.     LocalToGlobal( &where );
  111.  
  112.     /* Make a new floating window */
  113.     theWindow = FloatingWindowSetup( ResID( 1 ), ( FloatingWindowHandle )thePalette,
  114.                             ( ParentHandle )myFMAT, where );
  115.     if( !theWindow ) {
  116.         DisposHandle(( Handle )thePalette );
  117.         return 0;
  118.     }
  119.  
  120.     return thePalette;
  121. }
  122.  
  123. /* InitNumberPartsPalette: Position all buttons and text on the palette */
  124. void InitNumberPartsPalette( NumberPartsPaletteHandle thePalette, NumberParts *parts,
  125.                             short parentFont )
  126. {
  127.     Point                        where, loc;
  128.     Rect                        empty;
  129.     FontInfo                    info;
  130.     Str255                        s;
  131.  
  132.     WindowPtr                    theWindow;
  133.     long                        result;
  134.  
  135.     short                        lineHeight;
  136.     short                        tok;
  137.  
  138.  
  139.     theWindow = ( *thePalette )->fw.wind;
  140.     SetPort( theWindow );
  141.  
  142.     /* Determine the font to use (small fond of parent's font's script) */
  143.     result = GetScript( Font2Script( parentFont ), smScriptSmallFondSize );
  144.     TextFont( HiWord( result ));
  145.     TextSize( LoWord( result ));
  146.     GetFontInfo( &info );
  147.     lineHeight = info.ascent + info.descent + info.leading;
  148.  
  149.     /* Initialize the button rectangles */
  150.     SetPt( &where, 2, 2 );
  151.     SetRect( &empty, 0, 0, 0, 0 );
  152.  
  153.     /* Left & right quotes on either side of the descriptive text */
  154.     MakeButtonRect( thePalette, parts, tokLeftQuote, &where, lineHeight, info.widMax );
  155.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  156.     ( *thePalette )->staticTextList[ kLiteralStr - 1 ] = loc;
  157.     GetIndString( s, ResID( kNumberPartsStringID ), 1 );
  158.     where.h += StringWidth( s );
  159.     MakeButtonRect( thePalette, parts, tokRightQuote, &where, lineHeight, info.widMax );
  160.     NewButtonRow( &where, lineHeight );
  161.  
  162.     /* Plus & minus buttons */
  163.     MakeButtonRect( thePalette, parts, tokPlusSign, &where, lineHeight, info.widMax );
  164.     MakeButtonRect( thePalette, parts, tokMinusSign, &where, lineHeight, info.widMax );
  165.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  166.     ( *thePalette )->staticTextList[ kSignsStr - 1 ] = loc;
  167.     NewButtonRow( &where, lineHeight );
  168.  
  169.     /* Digit buttons */
  170.     MakeButtonRect( thePalette, parts, tokLeadPlacer, &where, lineHeight, info.widMax );
  171.     MakeButtonRect( thePalette, parts, tokZeroLead, &where, lineHeight, info.widMax );
  172.     MakeButtonRect( thePalette, parts, tokNonLeader, &where, lineHeight, info.widMax );
  173.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  174.     ( *thePalette )->staticTextList[ kDigitsStr - 1 ] = loc;
  175.     NewButtonRow( &where, lineHeight );
  176.  
  177.     /* Thousands button */
  178.     MakeButtonRect( thePalette, parts, tokThousands, &where, lineHeight, info.widMax );
  179.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  180.     ( *thePalette )->staticTextList[ kThousandsStr - 1 ] = loc;
  181.     NewButtonRow( &where, lineHeight );
  182.  
  183.     /* Decimal point button */
  184.     MakeButtonRect( thePalette, parts, tokDecPoint, &where, lineHeight, info.widMax );
  185.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  186.     ( *thePalette )->staticTextList[ kDecPointStr - 1 ] = loc;
  187.     NewButtonRow( &where, lineHeight );
  188.  
  189.     /* Percentage symbol button */
  190.     MakeButtonRect( thePalette, parts, tokPercent, &where, lineHeight, info.widMax );
  191.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  192.     ( *thePalette )->staticTextList[ kPercentStr - 1 ] = loc;
  193.     NewButtonRow( &where, lineHeight );
  194.  
  195.     /* Escape button */
  196.     MakeButtonRect( thePalette, parts, tokEscape, &where, lineHeight, info.widMax );
  197.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  198.     ( *thePalette )->staticTextList[ kEscapeStr - 1 ] = loc;
  199.     NewButtonRow( &where, lineHeight );
  200.  
  201.     /* Separator button */
  202.     MakeButtonRect( thePalette, parts, tokSeparator, &where, lineHeight, info.widMax );
  203.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  204.     ( *thePalette )->staticTextList[ kSeparatorStr - 1 ] = loc;
  205.     NewButtonRow( &where, lineHeight );
  206.  
  207.     /* These guys aren't used */
  208.     ( *thePalette )->buttonList[ tokLeader - 1 ] = empty;
  209.     ( *thePalette )->buttonList[ 11 - 1 ] = empty;
  210.     ( *thePalette )->buttonList[ tokPEMinusPlus - 1 ] = empty;
  211.  
  212.     /* E+ and E- buttons */
  213.     MakeButtonRect( thePalette, parts, tokPEPlus, &where, lineHeight, info.widMax );
  214.     MakeButtonRect( thePalette, parts, tokPEMinus, &where, lineHeight, info.widMax );
  215.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  216.     ( *thePalette )->staticTextList[ kExponentsStr - 1 ] = loc;
  217.     NewButtonRow( &where, lineHeight );
  218.  
  219.     /* Unquoted literals label */
  220.     SetPt( &loc, where.h, where.v + info.ascent + 3 );
  221.     ( *thePalette )->staticTextList[ kUnquotedStr - 1 ] = loc;
  222.     NewButtonRow( &where, lineHeight );
  223.  
  224.     /* Unquoted literals buttons */
  225.     for( tok = /*tokUnquoteds*/ 15; tok <= tokMaxSymbols; tok++ ) {
  226.         if( parts->data[ tok - 1 ].b )
  227.             MakeButtonRect( thePalette, parts, tok, &where, lineHeight, info.widMax );
  228.         else
  229.             ( *thePalette )->buttonList[ tok - 1 ] = empty;
  230.     }
  231.     NewButtonRow( &where, lineHeight );
  232.  
  233.     /* Resize the palette to accommodate all buttons */
  234.     SizeWindow( theWindow, theWindow->portRect.right, where.v, FALSE );
  235.     InvalRect( &theWindow->portRect );
  236. }
  237.  
  238. /* DrawTokenButton: Draw a token's button */
  239. static void DrawTokenButton( NumberPartsPaletteHandle thePalette, short tok,
  240.                         NumberParts *parts, WindowPtr theWindow, FontInfo *info )
  241. {
  242.     Rect                r;
  243.     Str31                token;
  244.  
  245.     short                center;
  246.  
  247.  
  248.     /* No need if not in visRgn */
  249.     r = ( *thePalette )->buttonList[ tok-1 ];
  250.     if( !RectInRgn( &r, theWindow->visRgn ))
  251.         return;
  252.  
  253.     /* Retrieve its string and center it */
  254.     GetButtonStr( parts, tok, token );
  255.     center = info->widMax - StringWidth( token );
  256.     if( center < 0 )
  257.         center = 0;
  258.     else
  259.         center >>= 1;
  260.  
  261.     /* Draw the button */
  262.     EraseRect( &r );
  263.     FrameRoundRect( &r, 6, 6 );
  264.     MoveTo( r.left + 3 + center, r.top + 3 + info->ascent );
  265.     DrawString( token );
  266. }
  267.  
  268. /* UpdatePalette: Handle update event for number parts palette */
  269. void UpdatePalette( NumberPartsPaletteHandle thePalette )
  270. {
  271.     Point                loc;
  272.     FontInfo            info;
  273.     NumberParts            parts;
  274.     Str255                s;
  275.  
  276.     WindowPtr            theWindow;
  277.  
  278.     short                tok, i, id;
  279.  
  280.  
  281.     theWindow = ( *thePalette )->fw.wind;
  282.     SetPort( theWindow );
  283.     EraseRgn( theWindow->visRgn );
  284.     GetFontInfo( &info );
  285.     parts = ( *( rFMATHandle )( *thePalette )->fw.father )->partsTable;
  286.  
  287.     /* Draw all buttons */
  288.     for( tok = tokLeftQuote; tok < kNumPaletteButtons; tok++ ) {
  289.         DrawTokenButton( thePalette, tok, &parts, theWindow, &info );
  290.     }
  291.  
  292.     /* Draw all text labels */
  293.     id = ResID( kNumberPartsStringID );
  294.     for( i = kLiteralStr; i < kNumPaletteStaticText; i++ ) {
  295.         GetIndString( s, id, i );
  296.         loc = ( *thePalette )->staticTextList[ i - 1 ];
  297.         MoveTo( loc.h, loc.v );
  298.         DrawString( s );
  299.     }
  300. }
  301.  
  302. /* ClickPaletteButton: Perform button operation */
  303. static void ClickPaletteButton( NumberPartsPaletteHandle thePalette, short tok )
  304. {
  305.     Str31                token;
  306.  
  307.     rFMATHandle            myFMAT;
  308.     TEHandle            hTE;
  309.  
  310.  
  311.     myFMAT = ( rFMATHandle )( *thePalette )->fw.father;
  312.     GetButtonStr( &( *myFMAT )->partsTable, tok, token );
  313.     hTE = (( DialogPeek )( *thePalette )->fw.ownerWindow )->textH;
  314.  
  315.     /* Delete selected text */
  316.     TEDelete( hTE );
  317.  
  318.     /* Insert token */
  319.     TEInsert( token + 1, Length( token ), hTE );
  320.  
  321.     /* Update the examples */
  322.     UpdateExamples( myFMAT );
  323. }
  324.  
  325. /* TrackRoundRect: Track mouse & provide visual feedback */
  326. static Boolean TrackRoundRect( Point where, Rect *r, short ovalWidth, short ovalHeight )
  327. {
  328.     Boolean            inside;
  329.     Point            oldPt, newPt;
  330.  
  331.  
  332.     /* Assume we start inside the rect */
  333.     inside = TRUE;
  334.     InvertRoundRect( r, ovalWidth, ovalHeight );
  335.     oldPt = where;
  336.  
  337.     /* Wait for button to be released */
  338.     while( StillDown()) {
  339.  
  340.         /* Get new mouse location and see if it's changed */
  341.         GetMouse( &newPt );
  342.         if( !DeltaPoint( oldPt, newPt ))
  343.             continue;
  344.  
  345.         /* Mouse has moved; use new location */
  346.         oldPt = newPt;
  347.  
  348.         /* See if status has changed */
  349.         if( PtInRect( oldPt, r ) == inside )
  350.             continue;
  351.  
  352.         /* Status has changed; invert the rect and switch status */
  353.         InvertRoundRect( r, ovalWidth, ovalHeight );
  354.         inside = !inside;
  355.     }
  356.  
  357.     /* If still inside after button release, turn the rect back off */
  358.     if( inside )
  359.         InvertRoundRect( r, ovalWidth, ovalHeight );
  360.  
  361.     /* Report success to caller */
  362.     return inside;
  363. }
  364.  
  365. /* ClickPalette: Handle a mouseDown event in the number parts palette */
  366. void ClickPalette( EventRecord *evt, NumberPartsPaletteHandle thePalette )
  367. {
  368.     Point                where;
  369.     Rect                r;
  370.  
  371.     WindowPtr            theWindow;
  372.  
  373.     short                tok;
  374.  
  375.  
  376.     theWindow = ( *thePalette )->fw.wind;
  377.     SetPort( theWindow );
  378.  
  379.     where = evt->where;
  380.     GlobalToLocal( &where );
  381.  
  382.     /* Find which button was clicked */
  383.     for( tok = tokLeftQuote; tok <= tokMaxSymbols + 3; tok++ ) {
  384.         r = ( *thePalette )->buttonList[ tok-1 ];
  385.         if( PtInRect( where, &r )) {
  386.  
  387.             /* Found it! Track mouse and perform action */
  388.             if( TrackRoundRect( where, &r, 6, 6 ))
  389.                 ClickPaletteButton( thePalette, tok );
  390.             break;
  391.         }
  392.     }
  393. }
  394.  
  395. /* CloseNumberPartsPalette: Free storage */
  396. void CloseNumberPartsPalette( NumberPartsPaletteHandle thePalette )
  397. {
  398.     WindowPtr                theWindow;
  399.  
  400.  
  401.     theWindow = ( *thePalette )->fw.wind;
  402.     CloseWindow( theWindow );
  403.     WindReturn( theWindow );
  404.  
  405.     DisposHandle(( Handle )thePalette );
  406. }
  407.